Chapter 10: Completing a Todo

Other than the common CRUD related kinds of operations, how do we implement views for customised logic? In

this chapter, we will see how to implement a view that completes a todo.

We first add a path to complete a todo by adding the below code:

todobackend/api/urls.py

Modify Bold Code

...

urlpatterns = [

path('todos/', views.TodoListCreate.as_view()),

path('todos/<int:pk>', views.TodoRetrieveUpdateDestroy.as_view()),

path('todos/<int:pk>/complete', views.TodoToggleComplete.as_view()),

]

That is, if a request is sent to localhost:8000/api/todos/123/complete, the todo with id ‘123’ will be marked as

complete.

Let’s implement the TodoToggleComplete view in todobackend/api/views.py:

Modify Bold Code

from rest_framework import generics, permissions

from .serializers import TodoSerializer, TodoToggleCompleteSerializer

from todo.models import Todo

class TodoListCreate(generics.ListCreateAPIView):

...

class TodoRetrieveUpdateDestroy(generics.RetrieveUpdateDestroyAPIView):

...

class TodoToggleComplete(generics.UpdateAPIView):

serializer_class = TodoToggleCompleteSerializer

permission_classes = [permissions.IsAuthenticated]

def get_queryset(self):

user = self.request.user

return Todo.objects.filter(user=user)

def perform_update(self,serializer):

serializer.instance.completed=not(serializer.instance.completed)

serializer.save()

Code Explanation

Analyze Code

class TodoToggleComplete(generics.UpdateAPIView):

As its name suggests, TodoToggleComplete toggles a todo from incomplete to complete and vice-versa.

TodoToggleComplete extends the UpdateAPIView used for update-only endpoints for a single model instance.

Analyze Code

serializer_class = TodoToggleCompleteSerializer

permission_classes = [permissions.IsAuthenticated]

We will implement the TodoToggleCompleteSerializer later on. Only authenticated users can mark a todo as

complete.

Analyze Code

def perform_update(self,serializer):

serializer.instance.completed=not(serializer.instance.completed)

serializer.save()

Similar to perform_create, perform_update is called before the update happens. In it, we ‘invert’ the todo’s

completed boolean value. i.e. if its true, set to false, if false, set to true.

todobackend/api/serializers.py

Let’s now implement the TodoToggleCompleteSerializer serializer. Add the below code to

todobackend/api/serializers.py: